package com.md.api.google;


import com.alibaba.fastjson.JSONObject;
import com.google.api.client.googleapis.auth.oauth2.*;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.md.api.common.config.RedisKeys;
import com.md.api.common.utils.*;
import com.md.api.dao.TbOrderVirtuallyMapper;
import com.md.api.dao.UserMapper;
import com.md.api.dao.UserVipMapper;
import com.md.api.dao.VipPropertiesMapper;
import com.md.api.entity.HttpResult;
import com.md.api.entity.UserInfo;
import com.md.api.entity.UserVip;
import com.md.api.entity.VipProperties;
import com.md.api.entity.enums.UserStatus;
import com.md.api.entity.enums.VipStatus;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.security.GeneralSecurityException;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class GoogleAuthService {


    @Resource
    GoogleAuthorization googleAuthorization;
    @Resource
    TbOrderVirtuallyMapper storageMapper;
    @Resource
    RedisUtil redisUtil;
    @Resource
    UserMapper userMapper;
    @Resource
    VipPropertiesMapper vipMapper;
    @Resource
    UserVipMapper userVipMapper;
    public String authorizingUrl(JSONObject json) throws GeneralSecurityException, IOException {
        HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
        JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
        // 创建验证流程对象
        GoogleAuthorizationCodeFlow googleAuthorizationCodeFlow = new GoogleAuthorizationCodeFlow
                .Builder(httpTransport, jsonFactory, googleAuthorization.getGoogleClientSecrets(), googleAuthorization.getScopes())
                // AccessType为离线offline，才能获得Refresh Token
                .setAccessType("offline").build();
        if (googleAuthorizationCodeFlow != null) {
            if (null!=json&&StringUtils.isNotEmpty(json.getString("redirectUrl"))){
                return googleAuthorizationCodeFlow.newAuthorizationUrl().setRedirectUri(json.getString("redirectUrl")).build();
            }else {
                // 返回跳转登录请求
                return googleAuthorizationCodeFlow.newAuthorizationUrl().setRedirectUri(googleAuthorization.getRedirectUrl()).build();
            }
        }
        return null;
    }



    public HttpResult authorizing(JSONObject json) throws GeneralSecurityException, IOException {
        try {
            // 创建请求凭证
            HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
            JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
            GoogleAuthorizationCodeFlow googleAuthorizationCodeFlow = new GoogleAuthorizationCodeFlow
                    .Builder(httpTransport, jsonFactory, googleAuthorization.getGoogleClientSecrets(), googleAuthorization.getScopes())
                    // AccessType为离线offline，才能获得Refresh Token
                    .setAccessType("offline").build();
            GoogleAuthorizationCodeTokenRequest tokenRequest = googleAuthorizationCodeFlow.newTokenRequest(json.getString("code"));
            if (null!=json&&StringUtils.isNotEmpty(json.getString("redirectUrl"))){
                tokenRequest.setRedirectUri(json.getString("redirectUrl"));
            }else {
                tokenRequest.setRedirectUri(googleAuthorization.getRedirectUrl());
            }

            tokenRequest.setGrantType("authorization_code");
            // 发起授权请求，获得Token和Refresh Token
            GoogleTokenResponse tokenResponse = null;
            try {
                tokenResponse = tokenRequest.execute();
            }catch (Exception e){
                e.printStackTrace();
            }
            String token = tokenResponse.getAccessToken();
            String refreshToken = tokenResponse.getRefreshToken();
            // 获得email
            String email = null;
            if (StringUtils.isNotEmpty(tokenResponse.getIdToken())) {
                GoogleIdTokenVerifier idTokenVerifier = new GoogleIdTokenVerifier.Builder(googleAuthorizationCodeFlow.getTransport(), googleAuthorizationCodeFlow.getJsonFactory()).build();
                idTokenVerifier.verify(tokenResponse.getIdToken());
                GoogleIdToken googleIdToken = idTokenVerifier.verify(tokenResponse.getIdToken());
                if (googleIdToken != null && googleIdToken.getPayload() != null) {
                    email = googleIdToken.getPayload().getEmail();
                    log.info("Google登录获取到邮箱地址："+email);
                }
            }
            UserInfo dbuser = userMapper.findByEmail(email);
            //存在且是注销的，更新状态
            if (null!=dbuser&&dbuser.getStatus()== UserStatus.LOG_OFF.value()){
                userMapper.updateStatus(dbuser.getUserId(),UserStatus.NORMAL.value());
            }
            //不存在就注册
            if (null==dbuser){
                UserInfo user = new UserInfo();
                user.setUserId(Md5Utils.encode(email));
                user.setEmail(email);
                user.setUserType(0);
                user.setNickName(email);
                //赠送免费次数
                List<VipProperties> freeServices = vipMapper.getFreeService();
                VipProperties freeService = freeServices.stream().max(Comparator.comparing(VipProperties::getWeight)).get();
                if (null!=freeService){
                    //初始创建会员购买
                    UserVip userVip = new UserVip();
                    userVip.setCurrentPrice(freeService.getCurrentPrice());
                    userVip.setPrice(freeService.getPrice());
                    userVip.setServiceCode(freeService.getServiceCode());
                    userVip.setServiceName(freeService.getServiceName());
                    userVip.setIsFacialRecognition(freeService.getIsFacialRecognition());
                    userVip.setIsCompression(freeService.getIsCompression());
                    userVip.setServiceDate(freeService.getServiceDate());
                    userVip.setDateType(freeService.getDateType());
                    if (freeService.getDateType()==1){
                        userVip.setTotalDay(365*freeService.getServiceDate());
                    }else if (freeService.getDateType()==2){
                        userVip.setTotalDay(30*freeService.getServiceDate());
                    }else if (freeService.getDateType()==5){
                        userVip.setTotalDay(freeService.getServiceDate());
                    }
                    userVip.setDownloadTypes(freeService.getDownloadTypes());
                    userVip.setIsFtp(freeService.getIsFtp());
                    userVip.setIsFree(freeService.getIsFree());
                    userVip.setIsOnline(freeService.getIsOnline());
                    userVip.setIsSecretVisit(freeService.getIsSecretVisit());
                    userVip.setIsHighSecret(freeService.getIsHighSecret());
                    userVip.setIsPoster(freeService.getIsPoster());
                    userVip.setAiTimes(freeService.getAiTimes());
                    userVip.setSurplusAiTimes(freeService.getAiTimes());
                    userVip.setStorage(freeService.getStorage());
                    userVip.setIsVideo(freeService.getIsVideo());
                    userVip.setIsLogo(freeService.getIsLogo());
                    userVip.setWeight(freeService.getWeight());
                    userVip.setUserId(user.getUserId());
                    userVip.setStatus(VipStatus.IN_EFFECT.value());
                    userVip.setEffectiveTime(new Date());
                    userVip.setPurchaseTime(new Date());
                    userVip.setExpiredTime(DateUtils.add(new Date(), freeService.getDateType(),freeService.getServiceDate()));
                    userVipMapper.insert(userVip);
                }
                userMapper.register(user);
                dbuser=user;
            }
            if (null!=dbuser.getUseStorage()&&dbuser.getUseStorage()>0){
                BigDecimal num1 = new BigDecimal(dbuser.getUseStorage());
                BigDecimal num2 = new BigDecimal(1024*1024*1024);
                dbuser.setUseStorage(num1.divide(num2,2, RoundingMode.HALF_UP).doubleValue());
            }
            dbuser.setStorage(storageMapper.getTotalEffectiveStorage(dbuser.getUserId()));
            dbuser.setCurrentVip(userVipMapper.getCurrentVip(dbuser.getUserId()));
            dbuser.setToken(token);
            dbuser.setGoogleRefreshToken(refreshToken);
            redisUtil.set(RedisKeys.getUserTokenInfoKey(token),dbuser,3600*24);
            return new HttpResult(dbuser);
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }


    public  String getUserInfo(String accessToken) {

        String url = "https://www.googleapis.com/oauth2/v1/userinfo?access_token=" + accessToken;
        try {
            return HttpUtil.doGet(url);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public String refreshToken(String refreshToken) throws IOException {
        String token = null;
        // 创建刷新请求对象
        GoogleRefreshTokenRequest googleRefreshTokenRequest = new GoogleRefreshTokenRequest(
                new NetHttpTransport(),
                JacksonFactory.getDefaultInstance(),
                refreshToken,
                googleAuthorization.getGoogleClientSecrets().getDetails().getClientId(),
                googleAuthorization.getGoogleClientSecrets().getDetails().getClientSecret());
        // 发起刷新请求
        GoogleTokenResponse googleTokenResponse = googleRefreshTokenRequest.execute();
        if (googleTokenResponse != null && StringUtils.isNotEmpty(googleTokenResponse.getAccessToken())) {
            token = googleTokenResponse.getAccessToken();
        }
        return null;
    }
}
